package com.module.app.base

import android.text.TextUtils
import androidx.annotation.CallSuper
import androidx.annotation.IdRes
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView
import com.module.app.bean.ListViewBean
import com.module.base.base.adapter.proxy.RefreshLayoutProxy
import com.module.base.network.ERROR
import com.module.base.network.exception.ServerException
import com.module.base.utils.CommonUtils
import com.module.base.utils.RecycleViewUtil
import com.module.base.utils.ToastUtils
import com.module.base.R
import com.module.base.base.adapter.BaseNewAdapter
import com.module.base.utils.LogUtils
import com.module.base.widget.recyclerview.NestVerticalRecyclerView
import com.module.frame.ext.observe

/**
 * @author yanxuwen
 * @date 2020/5/7 15:40
 * Description :
 * contract的View  需要继承IListView
 * RecyclerView 跟BsnlRefreshLayout id需要一致
 * 通用的列表
 */
abstract class BaseListFragment<VM : BaseViewModel, DB : ViewDataBinding, A : BaseNewAdapter<out Any>> :
    BaseFragment<VM, DB>() {
    val recyclerview: RecyclerView by lazy {
        mRootView.findViewById(R.id.recyclerview)
    }
    var refreshLayout: RefreshLayoutProxy? = null
    val adapter: A by lazy {
        createAdapter()
    }

    var isShowNoData = false
    var layoutManager: RecyclerView.LayoutManager? = null

    /**
     * 适配器
     */
    protected abstract fun createAdapter(): A

    /**
     * 列表数据加载。
     */
    protected abstract fun onListLoadPage(
        isPull: Boolean, isRefresh: Boolean, page_no: Int, page_size: Int
    )

    /**
     * 设置异常视图
     */
    @IdRes
    override fun getErrorViewRes(): Int {
        return R.id.recyclerview
    }

    /**
     * 默认 LinearLayoutManager
     */
    open fun getManager(): RecyclerView.LayoutManager? {
        if (layoutManager == null) {
            layoutManager = RecycleViewUtil.getLinear(context)
        }
        return layoutManager

    }

    @CallSuper
    override fun initView() {
        super.initView()
        refreshLayout = mRootView.findViewById(R.id.refreshLayout)
        recyclerview?.layoutManager = getManager()
        if (adapter.recyclerView == null) {
            adapter.bindToRecyclerView(recyclerview)
        }
        //使用adapter的无数据
        adapter.setAdapterNoData(true)
        if (refreshLayout != null) {
            refreshLayout?.onNestRecyclerview(recyclerview)
        }
        if (recyclerview is NestVerticalRecyclerView) {
            (recyclerview as NestVerticalRecyclerView).setNestDeal(true)
        }
    }

    @CallSuper
    override fun initListener() {
        super.initListener()
        adapter.setRefreshPageListenner(refreshLayout, recyclerview) { isPull, isRefresh ->
            onListLoadPage(
                isPull, isRefresh, adapter.page_no, adapter.page_size
            )
        }
        observe(mViewModel.listFlow) {
            setListData(it)
        }
        observe(mViewModel.errorFlow) {
            onListError(it)
        }
    }

    /**
     * 重新加载，,界面会先空白，设置成加载界面
     */
    override fun reload() {
        super.reload()
        adapter.autoRefresh()
    }

    /**
     * 刷新，保留现有的界面，展示出加载框
     */
    override fun refresh() {
        super.refresh()
        adapter.autoRefresh()
    }

    /**
     * 刷新，不显示加载框
     */
    fun refresh2() {
        adapter.autoRefresh()
    }

    /**
     * 设置列表数据
     */
    open fun setListData(bean: ListViewBean) {
        if (bean.isRefresh) {
            if (bean.list == null) {
                adapter.setNewData(mutableListOf())
            } else {
                adapter.setNewData(bean.list as List<Nothing>?)
            }
        } else {
            if (bean.list == null) {
                adapter.addData(mutableListOf())
            } else {
                adapter.addData(bean.list as List<Nothing>)
            }
        }
        //如果数据为空，但是没有关闭加载功能，则直接自动请求下一次接口，不在重新绘制LoadMore试图
        if (bean.list.isNullOrEmpty() && !bean.isNoMore) {
            onListLoadPage(
                isPull = false,
                isRefresh = false,
                page_no = adapter.page_no,
                page_size = adapter.page_size
            )
            return
        }
        showSuccess()
        adapter.loadMoreComplete(true)
        if (adapter.itemCount - adapter.loadMoreViewCount == 0 && (bean.list == null || bean.list.isEmpty())) {
            showEmpty()
        } else if (bean.isNoMore) {
            adapter.loadMoreEnd(isShowNoData)
        }
    }

    /**
     * 设置列表异常
     */
    fun onListError(exception: ServerException) {
        showSuccess()
        adapter.loadMoreComplete(false)
        if (adapter.itemCount - adapter.loadMoreViewCount == 0) {
            showError(exception)
        } else {
            adapter.loadMoreFail()
            ToastUtils.showShort(if (TextUtils.isEmpty(exception.message)) "异常" else exception.message)
        }
    }

    fun onListComplete() {
        showSuccess()
        adapter.loadMoreComplete(true)
        adapter.loadMoreEnd(isShowNoData)
    }

    fun onListCancel() {
        onListError(
            ServerException(
                CommonUtils.getString(R.string.error_unknow),
                ERROR.CANCEL
            )
        )
    }
}